/*
 * @Author: your name
 * @Date: 2021-11-18 09:50:22
 * @LastEditTime: 2021-11-18 10:13:58
 * @LastEditors: Please set LastEditors
 * @Description: 打开koroFileHeader查看配置 进行设置:
 * https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 * @FilePath: \rtspclient\src\rtp.cc
 */
#include "rtp.h"

#include <cassert>
#include <iostream>
#include <thread>
#include <unistd.h>

bool RtpDepay::UnpackRtpHead(PayloadType pt, u_char* rtp_head, RTP_HEADER_S& rtphead) {
    mempcpy(&rtphead, rtp_head, 2);
    /**RTP 序列号**/
    rtphead.u32SeqNum = 0;
    rtphead.u32SeqNum = (rtp_head[2] & 0xff);
    rtphead.u32SeqNum <<= 8;
    rtphead.u32SeqNum |= (rtp_head[3] & 0xff);
    /**RTP 时间戳**/
    rtphead.u32TimeStamp = (rtp_head[4] & 0xff);
    rtphead.u32TimeStamp <<= 8;
    rtphead.u32TimeStamp |= (rtp_head[5] & 0xff);
    rtphead.u32TimeStamp <<= 8;
    rtphead.u32TimeStamp |= (rtp_head[6] & 0xff);
    rtphead.u32TimeStamp <<= 8;
    rtphead.u32TimeStamp |= (rtp_head[7] & 0xff);

    if (rtphead.bit1Version == 2 && rtphead.bit7PayLoadType == pt) {
        if (last_u32SeqNum_ == 0 || abs(last_u32SeqNum_ - rtphead.u32SeqNum) < 10) {
            last_TimeStamp_ = rtphead.u32TimeStamp;
            last_u32SeqNum_ = rtphead.u32SeqNum;
            return true;
        }
    }

    return false;
}

std::string RtpDepay::GetRTCPRRMsg() {
    InterFrameHeader ifheader;
    ifheader.ch_num     = 1;
    std::string rrstr   = rtcp_msg_.GetRRMsg();
    std::string sdesstr = rtcp_msg_.GetSDESMsg();
    ifheader.data_len   = rrstr.length() + sdesstr.length();
    ifheader.data_len   = htons(ifheader.data_len);
    printf("rrstr-size:%d sdesstr-size:%d\n", rrstr.length(), sdesstr.length());
    std::string str;
    str.resize(sizeof(InterFrameHeader) + ntohs(ifheader.data_len));
    memcpy(&str[0], (char*)&ifheader, sizeof(InterFrameHeader));
    memcpy(&str[sizeof(InterFrameHeader)], rrstr.c_str(), rrstr.length());
    memcpy(&str[sizeof(InterFrameHeader) + rrstr.length()], sdesstr.c_str(), sdesstr.length());
    return str;
}

bool RtpDepay::PushRtpData(PayloadType pt, u_char* rtp_data, int len, bool close_flag) {
    if (rtp_data == NULL || len <= 0) {
        //数据流结尾
        return false;
    }

    std::vector<u_char> vdata(rtp_data, rtp_data + len);
    rtp_data_.insert(rtp_data_.end(), vdata.begin(), vdata.end());

    while (1) {
        u_char*          pd = (u_char*)&rtp_data_[0];
        InterFrameHeader ifheader;
        memcpy(&ifheader, pd, sizeof(InterFrameHeader));
        ifheader.data_len = ntohs(ifheader.data_len);  //返回一个以主机字节顺序表达的数 16bit
        if (ifheader.magic_num != 0x24 && !close_flag) {
            printf("ifheader.magic_num:0x%x\n", ifheader.magic_num);
        }
        if (ifheader.magic_num != 0x24 && close_flag) {
            return false;
        }
        assert(ifheader.magic_num == 0x24);

        if (rtp_data_.size() >= sizeof(InterFrameHeader) + ifheader.data_len) {
            one_rtp_pack_.resize(ifheader.data_len);
            memcpy(&one_rtp_pack_[0], pd + sizeof(InterFrameHeader), ifheader.data_len);
            if (ifheader.ch_num == 0) {
                if (depay_func_) {
                    depay_func_(pt, one_rtp_pack_);
                }
                one_rtp_pack_.clear();
            } else if (ifheader.ch_num == 1) {
                //接收到对方发过来的RTCP信息SR包时直接返回RR包，质量控制
                //暂时没实现，这里的RR包只充当心跳包功能
                std::string str = GetRTCPRRMsg();
                // str.copy((char*)&ifheader, sizeof(InterFrameHeader), 0);
                // str.copy(&rrstr[0], rrstr.length(), sizeof(InterFrameHeader));
                // str.copy(&sdesstr[0], sdesstr.length(), sizeof(InterFrameHeader) +
                // rrstr.length());
                if (rtcp_func_) {
                    rtcp_func_(str);
                }
            }
            rtp_data_.assign(rtp_data_.begin() + (sizeof(InterFrameHeader) + ifheader.data_len),
                             rtp_data_.end());
        } else {
            break;
        }
    }
    return true;
}